package com.nanhai.buddhist.college.module.collegebase.service.studentchange;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nanhai.buddhist.college.framework.common.pojo.PageResult;
import com.nanhai.buddhist.college.framework.common.util.collection.CollectionUtils;
import com.nanhai.buddhist.college.framework.common.util.number.NumberUtils;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.studentchange.vo.StudentChangeCheckReqVO;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.studentchange.vo.StudentChangeCreateReqVO;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.studentchange.vo.StudentChangeExportReqVO;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.studentchange.vo.StudentChangePageReqVO;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.studentchange.vo.StudentChangeRespVO;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.studentchange.vo.StudentChangeUpdateReqVO;
import com.nanhai.buddhist.college.module.collegebase.convert.studentchange.StudentChangeConvert;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.classes.ClassesDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.classes.ClassesInfoDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.colleges.CollegesDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.departments.DepartmentsDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.studentchange.StudentChangeDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.studentchangelog.StudentChangeLogDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.studentroll.StudentRollDO;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.classes.ClassesMapper;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.colleges.CollegesMapper;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.departments.DepartmentsMapper;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.professions.ProfessionsMapper;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.studentchange.StudentChangeMapper;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.studentchangelog.StudentChangeLogMapper;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.studentroll.StudentRollMapper;
import com.nanhai.buddhist.college.module.collegebase.enums.ErrorCodeConstants;
import com.nanhai.buddhist.college.module.collegebase.enums.StudentCheckStatusEnum;
import com.nanhai.buddhist.college.module.collegebase.service.classes.ClassesService;
import com.nanhai.buddhist.college.module.collegebase.service.studentroll.StudentRollService;
import com.nanhai.buddhist.college.module.collegebase.util.DateChangeUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import static com.nanhai.buddhist.college.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.nanhai.buddhist.college.module.collegebase.enums.ErrorCodeConstants.STUDENT_CHANGE_NOT_EXISTS;

/**
 * 学籍信息异动 Service 实现类
 *
 * @author Akai
 */
@Service
@Validated
public class StudentChangeServiceImpl implements StudentChangeService {

    @Resource
    private StudentChangeMapper studentChangeMapper;

    @Resource
    private StudentChangeLogMapper studentChangeLogMapper;

    @Resource
    private StudentRollMapper studentRollMapper;

    @Resource
    private CollegesMapper collegesMapper;
    @Resource
    private ClassesMapper classesMapper;
    @Resource
    private ProfessionsMapper professionsMapper;
    @Resource
    private DepartmentsMapper departmentsMapper;
    @Resource
    private StudentRollService studentRollService;
    @Resource
    private ClassesService classesService;


    @Override
    public String createStudentChange(StudentChangeCreateReqVO createReqVO) {
        // 插入
        StudentChangeDO studentChange = StudentChangeConvert.INSTANCE.convert(createReqVO);

        Long count = studentChangeMapper.selectCount(new LambdaQueryWrapper<StudentChangeDO>()
                .eq(StudentChangeDO::getChangeType, createReqVO.getChangeType())
                .eq(StudentChangeDO::getStudentId, createReqVO.getStudentId())
                .eq(StudentChangeDO::getCheckStatus, StudentCheckStatusEnum.AWAIT.getStatus()));
        if (ObjectUtil.isNotEmpty(count) && count > 0) {
            throw exception(ErrorCodeConstants.HAVE_CHANGE_ERROR);
        }

        studentChange.setChangeNumber(NumberUtils.getCodeByServ("YD"));
        studentChangeMapper.insert(studentChange);
        // 返回
        return studentChange.getId();
    }

    @Override
    public void updateStudentChange(StudentChangeUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateStudentChangeExists(updateReqVO.getId());
        // 更新
        StudentChangeDO updateObj = StudentChangeConvert.INSTANCE.convert(updateReqVO);
        studentChangeMapper.updateById(updateObj);
    }

    @Override
    public void deleteStudentChange(String id) {
        // 校验存在
        this.validateStudentChangeExists(id);
        // 删除
        studentChangeMapper.deleteById(id);
    }

    private void validateStudentChangeExists(String id) {
        if (studentChangeMapper.selectById(id) == null) {
            throw exception(STUDENT_CHANGE_NOT_EXISTS);
        }
    }

    @Override
    public StudentChangeDO getStudentChange(String id) {
        return studentChangeMapper.selectById(id);
    }

    @Override
    public List<StudentChangeDO> getStudentChangeList(Collection<String> ids) {
        return CollectionUtils.isEmpty(ids) ? Collections.emptyList() : studentChangeMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<StudentChangeDO> getStudentChangePage(StudentChangePageReqVO pageReqVO) {
        if (com.xkcoding.http.util.StringUtil.isNotEmpty(pageReqVO.getChangeEndTime())) {
            pageReqVO.setChangeEndTimeDate(DateChangeUtil.stringToDateEnd(pageReqVO.getChangeEndTime()));
        }
        if (com.xkcoding.http.util.StringUtil.isNotEmpty(pageReqVO.getChangeStartTime())) {
            pageReqVO.setChangeEndTimeDate(DateChangeUtil.stringToDateStart(pageReqVO.getChangeStartTime()));
        }
        return studentChangeMapper.selectPage(pageReqVO);
    }

    @Override
    public void setOldData(PageResult<StudentChangeRespVO> pageResultVo) {

        pageResultVo.getList().forEach(studentChangeRespVO -> {
            //获取原年级
            StudentRollDO studentRoll = studentRollService.getStudentRoll(studentChangeRespVO.getStudentId());
            if (studentRoll != null) {
                studentChangeRespVO.setOldYearGrade(studentRoll.getYearGrade());
                //获取机构编号
                DepartmentsDO departmentsDO = departmentsMapper.selectById(studentRoll.getDepartmentsId());
                if (ObjectUtil.isNotNull(departmentsDO)) {
                    CollegesDO collegesDO = collegesMapper.selectById(departmentsDO.getCollegeId());
                    if (ObjectUtil.isNotNull(departmentsDO)) {
                        studentChangeRespVO.setOrgId(collegesDO.getCollegeNumber());
                    }
                }
            }
            //获取现年级
            ClassesDO classes = classesService.getClasses(studentChangeRespVO.getNewClassGrade());
            if (classes != null) {
                studentChangeRespVO.setNewYearGrade(classes.getClassesGrade());
            }

        });
    }

    @Override
    public List<StudentChangeDO> getStudentChangeList(StudentChangeExportReqVO exportReqVO) {
        return studentChangeMapper.selectList(exportReqVO);
    }

    @Override
    @Transactional
    public void checkStudentChange(StudentChangeCheckReqVO req) {
        StudentChangeDO studentChangeDO = studentChangeMapper.selectById(req.getId());

        // 插入审核日志
        insetChangeLog(req, studentChangeDO);

        // 更新异动状态
        studentChangeDO.setCheckStatus(req.getCheckStatus());
        studentChangeDO.setCheckRemark(req.getCheckRemark());
        studentChangeDO.setCheckUser(req.getCheckUser());
        studentChangeMapper.updateById(studentChangeDO);

        // 审核通过同步修改 学生信息
        if (StudentCheckStatusEnum.PASS.getStatus().equals(req.getCheckStatus())) {
            StudentRollDO studentRollDO = studentRollMapper.selectById(studentChangeDO.getStudentId());
            studentRollDO.setDepartmentsId(studentChangeDO.getNewDepartment());
            studentRollDO.setClassesId(studentChangeDO.getNewClassGrade());
            studentRollDO.setProfessionsId(studentChangeDO.getNewMajor());
            //学院、系部、专业、班级昵称
            this.setName(studentRollDO);
            studentRollMapper.updateById(studentRollDO);
        }

    }

    private void insetChangeLog(StudentChangeCheckReqVO req, StudentChangeDO studentChangeDO) {
        StudentChangeLogDO studentChangeLogDO = new StudentChangeLogDO();
        studentChangeLogDO.setCheckTime(new Date());
        studentChangeLogDO.setChangeId(req.getId());
        studentChangeLogDO.setNewStatus(req.getCheckStatus());
        studentChangeLogDO.setOldStatus(studentChangeDO.getCheckStatus());
        studentChangeLogMapper.insert(studentChangeLogDO);
    }

    private void setName(StudentRollDO studentRoll) {
        ClassesInfoDO classesInfoDO = classesMapper.selectClassBaseInfoByClassesIdSelectOne(studentRoll.getClassesId());
        if (ObjectUtil.isNull(classesInfoDO)) {
            throw exception(ErrorCodeConstants.NOT_CLASSES_INFO_ERROR);
        }
        studentRoll.setCollege(classesInfoDO.getCollegeName());
        studentRoll.setClassGrade(classesInfoDO.getClassesName());
        studentRoll.setMajor(classesInfoDO.getProfessionsName());
        studentRoll.setDepartment(classesInfoDO.getDepartmentsName());
        studentRoll.setSerialNumber(NumberUtils.getCodeByServ("XY"));
    }
}
